﻿package fl.controls
{
    import fl.core.*;
    import fl.events.*;
    import fl.managers.*;
    import flash.display.*;
    import flash.events.*;
    import flash.ui.*;

    public class NumericStepper extends UIComponent implements IFocusManagerComponent
    {
        protected var inputField:TextInput;
        protected var upArrow:BaseButton;
        protected var downArrow:BaseButton;
        protected var _maximum:Number = 10;
        protected var _minimum:Number = 0;
        protected var _value:Number = 1;
        protected var _stepSize:Number = 1;
        protected var _precision:Number;
        private static var defaultStyles:Object = {downArrowDisabledSkin:"NumericStepperDownArrow_disabledSkin", downArrowDownSkin:"NumericStepperDownArrow_downSkin", downArrowOverSkin:"NumericStepperDownArrow_overSkin", downArrowUpSkin:"NumericStepperDownArrow_upSkin", upArrowDisabledSkin:"NumericStepperUpArrow_disabledSkin", upArrowDownSkin:"NumericStepperUpArrow_downSkin", upArrowOverSkin:"NumericStepperUpArrow_overSkin", upArrowUpSkin:"NumericStepperUpArrow_upSkin", upSkin:"TextInput_upSkin", disabledSkin:"TextInput_disabledSkin", focusRect:null, focusRectSkin:null, focusRectPadding:null, repeatDelay:500, repeatInterval:35, embedFonts:false};
        static const DOWN_ARROW_STYLES:Object = {disabledSkin:"downArrowDisabledSkin", downSkin:"downArrowDownSkin", overSkin:"downArrowOverSkin", upSkin:"downArrowUpSkin", repeatDelay:"repeatDelay", repeatInterval:"repeatInterval"};
        static const UP_ARROW_STYLES:Object = {disabledSkin:"upArrowDisabledSkin", downSkin:"upArrowDownSkin", overSkin:"upArrowOverSkin", upSkin:"upArrowUpSkin", repeatDelay:"repeatDelay", repeatInterval:"repeatInterval"};
        static const TEXT_INPUT_STYLES:Object = {upSkin:"upSkin", disabledSkin:"disabledSkin", textPadding:"textPadding", textFormat:"textFormat", disabledTextFormat:"disabledTextFormat", embedFonts:"embedFonts"};

        public function NumericStepper()
        {
            this.setStyles();
            this.stepSize = this._stepSize;
            return;
        }// end function

        override public function get enabled() : Boolean
        {
            return super.enabled;
        }// end function

        override public function set enabled(param1:Boolean) : void
        {
            if (param1 == this.enabled)
            {
                return;
            }
            super.enabled = param1;
            var _loc_2:* = param1;
            this.inputField.enabled = param1;
            var _loc_2:* = _loc_2;
            this.downArrow.enabled = _loc_2;
            this.upArrow.enabled = _loc_2;
            return;
        }// end function

        public function get maximum() : Number
        {
            return this._maximum;
        }// end function

        public function set maximum(param1:Number) : void
        {
            this._maximum = param1;
            if (this._value > this._maximum)
            {
                this.setValue(this._maximum, false);
            }
            return;
        }// end function

        public function get minimum() : Number
        {
            return this._minimum;
        }// end function

        public function set minimum(param1:Number) : void
        {
            this._minimum = param1;
            if (this._value < this._minimum)
            {
                this.setValue(this._minimum, false);
            }
            return;
        }// end function

        public function get nextValue() : Number
        {
            var _loc_1:* = this._value + this._stepSize;
            return this.inRange(_loc_1) ? (_loc_1) : (this._value);
        }// end function

        public function get previousValue() : Number
        {
            var _loc_1:* = this._value - this._stepSize;
            return this.inRange(_loc_1) ? (_loc_1) : (this._value);
        }// end function

        public function get stepSize() : Number
        {
            return this._stepSize;
        }// end function

        public function set stepSize(param1:Number) : void
        {
            this._stepSize = param1;
            this._precision = this.getPrecision();
            this.setValue(this._value);
            return;
        }// end function

        public function get value() : Number
        {
            return this._value;
        }// end function

        public function set value(param1:Number) : void
        {
            this.setValue(param1, false);
            return;
        }// end function

        public function get textField() : TextInput
        {
            return this.inputField;
        }// end function

        public function get imeMode() : String
        {
            return this.inputField.imeMode;
        }// end function

        public function set imeMode(param1:String) : void
        {
            this.inputField.imeMode = param1;
            return;
        }// end function

        override protected function configUI() : void
        {
            super.configUI();
            this.upArrow = new BaseButton();
            copyStylesToChild(this.upArrow, UP_ARROW_STYLES);
            this.upArrow.autoRepeat = true;
            this.upArrow.setSize(21, 12);
            this.upArrow.focusEnabled = false;
            addChild(this.upArrow);
            this.downArrow = new BaseButton();
            copyStylesToChild(this.downArrow, DOWN_ARROW_STYLES);
            this.downArrow.autoRepeat = true;
            this.downArrow.setSize(21, 12);
            this.downArrow.focusEnabled = false;
            addChild(this.downArrow);
            this.inputField = new TextInput();
            copyStylesToChild(this.inputField, TEXT_INPUT_STYLES);
            this.inputField.restrict = "0-9\\-\\.\\,";
            this.inputField.text = this._value.toString();
            this.inputField.setSize(21, 24);
            this.inputField.focusTarget = this as IFocusManagerComponent;
            this.inputField.focusEnabled = false;
            this.inputField.addEventListener(FocusEvent.FOCUS_IN, this.passEvent);
            this.inputField.addEventListener(FocusEvent.FOCUS_OUT, this.passEvent);
            addChild(this.inputField);
            this.inputField.addEventListener(Event.CHANGE, this.onTextChange, false, 0, true);
            this.upArrow.addEventListener(ComponentEvent.BUTTON_DOWN, this.stepperPressHandler, false, 0, true);
            this.downArrow.addEventListener(ComponentEvent.BUTTON_DOWN, this.stepperPressHandler, false, 0, true);
            return;
        }// end function

        protected function setValue(param1:Number, param2:Boolean = true) : void
        {
            if (param1 == this._value)
            {
                return;
            }
            var _loc_3:* = this._value;
            this._value = this.getValidValue(param1);
            this.inputField.text = this._value.toString();
            if (param2)
            {
                dispatchEvent(new Event(Event.CHANGE, true));
            }
            return;
        }// end function

        override protected function keyDownHandler(event:KeyboardEvent) : void
        {
            if (!this.enabled)
            {
                return;
            }
            event.stopImmediatePropagation();
            var _loc_2:* = Number(this.inputField.text);
            switch(event.keyCode)
            {
                case Keyboard.END:
                {
                    this.setValue(this.maximum);
                    break;
                }
                case Keyboard.HOME:
                {
                    this.setValue(this.minimum);
                    break;
                }
                case Keyboard.UP:
                {
                    this.setValue(this.nextValue);
                    break;
                }
                case Keyboard.DOWN:
                {
                    this.setValue(this.previousValue);
                    break;
                }
                case Keyboard.ENTER:
                {
                    this.setValue(_loc_2);
                    break;
                }
                default:
                {
                    break;
                }
            }
            return;
        }// end function

        protected function stepperPressHandler(event:ComponentEvent) : void
        {
            this.setValue(Number(this.inputField.text), false);
            switch(event.currentTarget)
            {
                case this.upArrow:
                {
                    this.setValue(this.nextValue);
                    break;
                }
                case this.downArrow:
                {
                    this.setValue(this.previousValue);
                }
                default:
                {
                    break;
                }
            }
            this.inputField.setFocus();
            this.inputField.textField.setSelection(0, 0);
            return;
        }// end function

        override public function drawFocus(param1:Boolean) : void
        {
            var _loc_2:Number = NaN;
            super.drawFocus(param1);
            if (param1)
            {
                _loc_2 = Number(getStyleValue("focusRectPadding"));
                uiFocusRect.width = width + _loc_2 * 2;
                uiFocusRect.height = height + _loc_2 * 2;
            }
            return;
        }// end function

        override protected function focusOutHandler(event:FocusEvent) : void
        {
            if (event.eventPhase == 3)
            {
                this.setValue(Number(this.inputField.text));
            }
            super.focusOutHandler(event);
            return;
        }// end function

        override protected function draw() : void
        {
            if (isInvalid(InvalidationType.STYLES, InvalidationType.STATE))
            {
                this.setStyles();
                invalidate(InvalidationType.SIZE, false);
            }
            if (isInvalid(InvalidationType.SIZE))
            {
                this.drawLayout();
            }
            if (isFocused && focusManager.showFocusIndicator)
            {
                this.drawFocus(true);
            }
            validate();
            return;
        }// end function

        protected function drawLayout() : void
        {
            var _loc_1:Number = NaN;
            _loc_1 = width - this.upArrow.width;
            var _loc_2:* = height / 2;
            this.inputField.setSize(_loc_1, height);
            this.upArrow.height = _loc_2;
            this.downArrow.height = Math.floor(_loc_2);
            this.downArrow.move(_loc_1, _loc_2);
            this.upArrow.move(_loc_1, 0);
            this.downArrow.drawNow();
            this.upArrow.drawNow();
            this.inputField.drawNow();
            return;
        }// end function

        protected function onTextChange(event:Event) : void
        {
            event.stopImmediatePropagation();
            return;
        }// end function

        protected function passEvent(event:Event) : void
        {
            dispatchEvent(event);
            return;
        }// end function

        override public function setFocus() : void
        {
            if (stage)
            {
                stage.focus = this.inputField.textField;
            }
            return;
        }// end function

        override protected function isOurFocus(param1:DisplayObject) : Boolean
        {
            return param1 == this.inputField || super.isOurFocus(param1);
        }// end function

        protected function setStyles() : void
        {
            copyStylesToChild(this.downArrow, DOWN_ARROW_STYLES);
            copyStylesToChild(this.upArrow, UP_ARROW_STYLES);
            copyStylesToChild(this.inputField, TEXT_INPUT_STYLES);
            return;
        }// end function

        protected function inRange(param1:Number) : Boolean
        {
            return param1 >= this._minimum && param1 <= this._maximum;
        }// end function

        protected function inStep(param1:Number) : Boolean
        {
            return (param1 - this._minimum) % this._stepSize == 0;
        }// end function

        protected function getValidValue(param1:Number) : Number
        {
            if (isNaN(param1))
            {
                return this._value;
            }
            var _loc_2:* = Number((this._stepSize * Math.round(param1 / this._stepSize)).toFixed(this._precision));
            if (_loc_2 > this.maximum)
            {
                return this.maximum;
            }
            if (_loc_2 < this.minimum)
            {
                return this.minimum;
            }
            return _loc_2;
        }// end function

        protected function getPrecision() : Number
        {
            var _loc_1:* = this._stepSize.toString();
            if (_loc_1.indexOf(".") == -1)
            {
                return 0;
            }
            return _loc_1.split(".").pop().length;
        }// end function

        public static function getStyleDefinition() : Object
        {
            return defaultStyles;
        }// end function

    }
}
